home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / tex / archives / pbmtopk.lzh / pbmtopk / src / pktopbm.c < prev    next >
C/C++ Source or Header  |  1992-05-16  |  9KB  |  383 lines

  1. /*
  2.   pktopbm, adapted from "pktopx in C by Tomas Rokicki" by AJCD 1/8/90
  3.  
  4.   compile with: cc -lpbm -o pktopbm pktopbm.c
  5.   */
  6.  
  7. #include <stdio.h>
  8. #include <pbm.h>
  9.  
  10. #define NAMELENGTH 80
  11. #define MAXROWWIDTH 3200
  12. #define MAXPKCHAR 256
  13.  
  14. #define round(a) ((int)(a+0.5))
  15.  
  16. typedef int integer ;
  17. typedef unsigned char quarterword ;
  18. typedef char boolean ;
  19. typedef quarterword eightbits ;
  20. typedef FILE *bytefile ;
  21.  
  22. bytefile pkfile ;
  23. char pkname[NAMELENGTH+1] ;
  24. integer pkloc ;
  25. integer i, j ;
  26. char *filename[MAXPKCHAR] ;
  27. bit **bitmap = NULL ;
  28. integer dynf ;
  29. eightbits inputbyte ;
  30. eightbits bitweight ;
  31. integer repeatcount ;
  32. integer flagbyte ;
  33.  
  34. add_suffix(name, suffix)
  35.      char *name, *suffix ;
  36. {
  37.   int haveext = 0;
  38.   if (name) {
  39.     while (*name) {
  40.       if (*name == '/') haveext = 0 ;
  41.       else if (*name == '.') haveext = 1 ;
  42.       name++ ;
  43.     }
  44.     if (!haveext) {
  45.       *name++ = '.';
  46.       strcpy(name,suffix) ;
  47.     }
  48.   }
  49. }
  50.  
  51. initialize()
  52. {
  53.   integer i ;
  54.  
  55.   fprintf(stderr, "This is PKtoPBM, C Version 2.3\n") ;
  56.   for (i = 0 ; i < MAXPKCHAR ; i ++) filename[i] = NULL ;
  57. }
  58.  
  59. jumpout()
  60. {
  61.   exit(1) ;
  62. }
  63.  
  64. openpkfile()
  65. {
  66.   if ((pkfile = fopen(pkname, "r")) == NULL) {
  67.     fprintf(stderr, " Can't open pk file %s!\n", pkname) ;
  68.   }
  69.   pkloc = 0 ;
  70. }
  71.  
  72. eightbits pkbyte()
  73. {
  74.   pkloc++ ;
  75.   return(getc(pkfile)) ;
  76. }
  77.  
  78. integer get16()
  79. {
  80.   integer a = pkbyte() ;
  81.   return((a<<8) + pkbyte()) ;
  82. }
  83.  
  84. integer get32()
  85. {
  86.   integer a = get16() ;
  87.   if (a > 32767) a -= 65536 ;
  88.   return((a<<16) + get16()) ;
  89. }
  90.  
  91. integer getnyb()
  92. {
  93.   eightbits temp ;
  94.   if (bitweight == 0) {
  95.     inputbyte = pkbyte() ;
  96.     bitweight = 16 ;
  97.   }
  98.   temp = inputbyte / bitweight ;
  99.   inputbyte -= temp * bitweight ;
  100.   bitweight >>= 4 ;
  101.   return(temp) ;
  102. }
  103.  
  104. boolean getbit()
  105. {
  106.   boolean temp ;
  107.   bitweight >>= 1 ;
  108.   if (bitweight == 0) {
  109.     inputbyte = pkbyte() ;
  110.     bitweight = 128 ;
  111.   }
  112.   temp = (inputbyte >= bitweight) ;
  113.   if (temp) inputbyte -= bitweight ;
  114.   return(temp) ;
  115. }
  116.  
  117. integer pkpackednum()
  118. {
  119.   integer i, j, k ;
  120.   i = getnyb() ;
  121.   if (i == 0) {
  122.     do {
  123.       j = getnyb() ;
  124.       i++ ;
  125.     } while (!(j != 0)) ;
  126.     while (i > 0) {
  127.       j = (j<<4) + getnyb() ;
  128.       i-- ;
  129.     }
  130.     return(j - 15 +((13 - dynf)<<4) + dynf) ;
  131.   } else if (i <= dynf) return(i) ;
  132.   else if (i < 14) return(((i - dynf - 1)<<4) + getnyb() + dynf + 1) ;
  133.   else {
  134.     if (i == 14) repeatcount = pkpackednum() ;
  135.     else repeatcount = 1 ;
  136.     return(pkpackednum()) ;
  137.   }
  138. }
  139.  
  140. skipspecials()
  141. {
  142.   integer i, j, k ;
  143.   do {
  144.     flagbyte = pkbyte() ;
  145.     if (flagbyte >= 240)
  146.       switch(flagbyte) {
  147.       case 240:
  148.       case 241:
  149.       case 242:
  150.       case 243:
  151.         i = 0 ;
  152.         for (j = 240 ; j <= flagbyte ; j ++) i = (i<<8) + pkbyte() ;
  153.         for (j = 1 ; j <= i ; j ++) k = pkbyte() ;
  154.         break ;
  155.       case 244:
  156.         i = get32() ;
  157.         break ;
  158.       case 245:
  159.         break ;
  160.       case 246:
  161.         break ;
  162.       case 247:
  163.       case 248:
  164.       case 249:
  165.       case 250:
  166.       case 251:
  167.       case 252:
  168.       case 253:
  169.       case 254:
  170.       case 255:
  171.         fprintf(stderr, " Unexpected flag byte %d!\n", flagbyte) ;
  172.         jumpout() ;
  173.       }
  174.   } while (!((flagbyte < 240) || (flagbyte == 245))) ;
  175. }
  176.  
  177. usage()
  178. {
  179.   fprintf(stderr, " Usage: pktopbm pkfile[.pk] [[-c num] pbmfile]...\n");
  180.   jumpout() ;
  181. }
  182.  
  183. dialog(gargc, gargv)
  184.      int gargc ;
  185.      char **gargv ;
  186. {
  187.   integer car ;
  188.  
  189.   if (--gargc < 1) usage() ;
  190.   strcpy(pkname, *++gargv) ;
  191.   add_suffix(pkname, "pk") ;
  192.   car = 0 ;
  193.   while (++gargv, --gargc) {
  194.     if (gargv[0][0] == '-' && gargv[0][1])
  195.       switch (gargv[0][1]) {
  196.       case 'c':
  197.         if (gargv[0][2]) car = atoi(*gargv+2) ;
  198.         else if (++gargv, --gargc) car = atoi(*gargv) ;
  199.         else usage() ;
  200.         break ;
  201.       default:
  202.         usage() ;
  203.       } else if (car < 0 || car >= MAXPKCHAR) {
  204.         fprintf(stderr, " Character must be in range 0 to %d (-c)!\n",
  205.                 MAXPKCHAR-1) ;
  206.         jumpout() ;
  207.       } else filename[car++] = *gargv ;
  208.   }
  209. }
  210.  
  211. main(argc, argv)
  212.      int argc ;
  213.      char *argv[] ;
  214. {
  215.   integer endofpacket ;
  216.   integer designsize ;
  217.   integer checksum ;
  218.   integer hppp, vppp ;
  219.   integer cheight, cwidth ;
  220.   integer horesc ;
  221.   integer packetlength ;
  222.   integer rowsleft ;
  223.   boolean turnon ;
  224.   integer hbit ;
  225.   integer count ;
  226.   integer rp ;
  227.   integer i, j, k ;
  228.   integer car ;
  229.   bit row[MAXROWWIDTH+1] ;
  230.  
  231.   initialize() ;
  232.   dialog(argc, argv) ;
  233.   openpkfile() ;
  234.   if (pkbyte() != 247) {
  235.     fprintf(stderr, " Bad pk file (pre command missing)!\n") ;
  236.     jumpout() ;
  237.   }
  238.   if (pkbyte() != 89) {
  239.     fprintf(stderr, " Wrong version of packed file!\n") ;
  240.     jumpout() ;
  241.   }
  242.   j = pkbyte() ;
  243.   for (i = 1 ; i <= j ; i ++) k = pkbyte() ;
  244.   designsize = get32() ;
  245.   checksum = get32() ;
  246.   hppp = get32() ;
  247.   vppp = get32() ;
  248.   if (hppp != vppp) fprintf(stderr, " Warning: aspect ratio not 1:1!\n") ;
  249.   skipspecials() ;
  250.   while (flagbyte != 245) {
  251.     dynf = (flagbyte>>4) ;
  252.     flagbyte &= 15 ;
  253.     turnon = (flagbyte >= 8) ;
  254.     if (turnon) flagbyte &= 7 ;
  255.     if (flagbyte == 7) {
  256.       packetlength = get32() ;
  257.       car = get32() ;
  258.       endofpacket = packetlength + pkloc ;
  259.       if ((car >= MAXPKCHAR) || (car < 0)) goto lab9997 ;
  260.       i = get32() ; /* tfmwidth */
  261.       horesc = get32() ;
  262.       i = get32() ;
  263.       cwidth = get32() ;
  264.       cheight = get32() ;
  265.       if ((cwidth < 0) || (cheight < 0) || (cwidth > 65535) || (cheight > 65535)) goto lab9997 ;
  266.       i = get32() ;
  267.       j = get32() ;
  268.     } else if (flagbyte > 3) {
  269.       packetlength =((flagbyte - 4)<<16) + get16() ;
  270.       car = pkbyte() ;
  271.       endofpacket = packetlength + pkloc ;
  272.       if (car >= MAXPKCHAR) goto lab9997 ;
  273.       i = pkbyte() ; /* tfmwidth */
  274.       i = get16() ;
  275.       horesc = get16() ;
  276.       cwidth = get16() ;
  277.       cheight = get16() ;
  278.       i = get16() ;
  279.       j = get16() ;
  280.     } else {
  281.       packetlength = (flagbyte<<8) + pkbyte() ;
  282.       car = pkbyte() ;
  283.       endofpacket = packetlength + pkloc ;
  284.       if (car >= MAXPKCHAR) goto lab9997 ;
  285.       i = pkbyte() ; /* tfmwidth */
  286.       i = get16() ;
  287.       horesc = pkbyte() ;
  288.       cwidth = pkbyte() ;
  289.       cheight = pkbyte() ;
  290.       i = pkbyte() ;
  291.       j = pkbyte() ;
  292.     }
  293.     if (filename[car]) {
  294.       bitmap = pbm_allocarray(cwidth, cheight) ;
  295.       if (bitmap == NULL) {
  296.         fprintf(stderr, " Out of memory allocating bitmap!\n") ;
  297.         jumpout() ;
  298.       }
  299.     } else goto lab9997 ;
  300.     bitweight = 0 ;
  301.     if (dynf == 14) {
  302.       for (i = 0 ; i < cheight ; i ++)
  303.         for (j = 0 ; j < cwidth ; j ++) {
  304.           if (getbit())
  305.             bitmap[i][j] = PBM_BLACK ;
  306.           else
  307.             bitmap[i][j] = PBM_WHITE ;
  308.         }
  309.     } else {
  310.       rowsleft = cheight ;
  311.       hbit = cwidth ;
  312.       repeatcount = rp =0 ;
  313.       while (rowsleft > 0) {
  314.         count = pkpackednum() ;
  315.         while (count > 0) {
  316.           if (count < hbit) {
  317.             hbit -= count ;
  318.             while (count--) {
  319.               if (turnon)
  320.                 row[rp++] = PBM_BLACK ;
  321.               else
  322.                 row[rp++] = PBM_WHITE ;
  323.             }
  324.           } else {
  325.             count -= hbit ;
  326.             while (hbit--) {
  327.               if (turnon)
  328.                 row[rp++] = PBM_BLACK ;
  329.               else
  330.                 row[rp++] = PBM_WHITE ;
  331.             }
  332.             for (i = 0; i <= repeatcount; i++)
  333.               for (j = 0; j < cwidth; j++)
  334.                 bitmap[i + cheight-rowsleft][j] = row[j] ;
  335.             rowsleft -= repeatcount + 1;
  336.             repeatcount = rp = 0 ;
  337.             hbit = cwidth ;
  338.           }
  339.         }
  340.         turnon = ! turnon ;
  341.       }
  342.       if ((rowsleft != 0) || (hbit != cwidth)) {
  343.         fprintf(stderr, " Bad pk file (more bits than required)!\n") ;
  344.         jumpout() ;
  345.       }
  346.     }
  347.     if (endofpacket != pkloc) {
  348.       fprintf(stderr, " Bad pk file (bad packet length)!\n") ;
  349.       jumpout() ;
  350.     }
  351.     /* output bitmap to file */
  352.     {
  353.       FILE *fp ;
  354.       if (!strcmp(filename[car], "-"))
  355.         fp = stdout ;
  356.       else {
  357.         if ((fp = fopen(filename[car], "w")) == NULL) {
  358.           fprintf(stderr, " Can't open file %s!\n", filename[car]) ;
  359.           jumpout() ;
  360.         }
  361.       }
  362.       filename[car] = NULL;
  363.       pbm_writepbm(fp, bitmap, cwidth, cheight, 0) ;
  364.       pbm_freearray(bitmap, cheight) ;
  365.       if (fp != stdout) (void)fclose(fp) ;
  366.     }
  367.     goto lab9998 ;
  368.   lab9997: while (pkloc != endofpacket) i = pkbyte() ;
  369.     if (car < 0 || car >= MAXPKCHAR)
  370.       fprintf(stderr, " Character %d out of range!\n", car) ;
  371.   lab9998: skipspecials() ;
  372.   }
  373.   while (! feof(pkfile)) i = pkbyte() ;
  374.   pkloc-- ;
  375.   for (car = 0; car < MAXPKCHAR; car++)
  376.     if (filename[car])
  377.       fprintf(stderr, " Warning: No character in position %d (file %s).\n",
  378.               car, filename[car]) ;
  379.   fprintf(stderr, "%d bytes read from packed file.\n", pkloc) ;
  380.   exit(0);
  381. }
  382.  
  383.